package dai.samples.mongodb.service.impl;

import dai.samples.mongodb.bean.OrderAndUserVo;
import dai.samples.mongodb.bean.OrderVo;
import dai.samples.mongodb.bean.UserGroupVo;
import dai.samples.mongodb.entity.Order;
import dai.samples.mongodb.entity.UserGroup;
import dai.samples.mongodb.service.LookUpService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.*;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * 联表查询的相关例子
 */
@Service
public class LookUpServiceImpl implements LookUpService {

    @Autowired
    MongoTemplate mongoTemplate;

    /**
     * 将一个集合和另外一个集合联结，一对一
     * @return
     */
    @Override
    public List<OrderVo> queryOrderAndUserInfo() {

        Criteria criteria = new Criteria();
        MatchOperation match = Aggregation.match(criteria);
        // 和另外一个集合进行关联，将其作为其属性
        LookupOperation lookup = Aggregation.lookup("UserInfo",// 连接表
            "userId",// 查询表中字段
            "_id",// 连接表中字段
            "userInfo");// 返回数据所在的属性名称
        TypedAggregation<Order> noRepeatAggregation2 =
            Aggregation.newAggregation(Order.class,match,lookup);

        AggregationResults<OrderVo> noRepeatDataInfoVos2 = mongoTemplate.aggregate(noRepeatAggregation2, OrderVo.class);
        List<OrderVo> noRepeatDataList2 = noRepeatDataInfoVos2.getMappedResults();
        return noRepeatDataList2;
    }

    @Override
    public List<OrderAndUserVo> queryOrderUserInfo() {
        Criteria criteria = new Criteria();
        MatchOperation match = Aggregation.match(criteria);
        // 和另外一个集合进行关联，将其作为其属性
        LookupOperation lookup = Aggregation.lookup("UserInfo",// 连接表
            "userId",// 查询表中字段
            "_id",// 连接表中字段
            "userInfo");// 返回数据所在的属性名称
        Field userName = Fields.field("userName", "userInfo.userName");
        ProjectionOperation project = Aggregation.project("id","totalMoney","totalProduct","userId","type")
            .andInclude(Fields.from(userName));
        TypedAggregation<Order> noRepeatAggregation2 =
            Aggregation.newAggregation(Order.class,match,lookup,project);

        AggregationResults<OrderAndUserVo> noRepeatDataInfoVos2 = mongoTemplate.aggregate(noRepeatAggregation2, OrderAndUserVo.class);
        List<OrderAndUserVo> noRepeatDataList2 = noRepeatDataInfoVos2.getMappedResults();
        return noRepeatDataList2;
    }

    @Override
    public List<UserGroupVo> queryUserGroup() {
        Criteria criteria = new Criteria();
        MatchOperation match = Aggregation.match(criteria);
        // 和另外一个集合进行关联，将其作为其属性
        LookupOperation lookup = Aggregation.lookup("UserInfo",// 连接表
            "name",// 查询表中字段
            "groupName",// 连接表中字段
            "UserInfos");
        //Aggregation.unwind("UserInfos");
        TypedAggregation<UserGroup> noRepeatAggregation2 =
            Aggregation.newAggregation(UserGroup.class,match,lookup);

        AggregationResults<UserGroupVo> noRepeatDataInfoVos2 = mongoTemplate.aggregate(noRepeatAggregation2, UserGroupVo.class);
        List<UserGroupVo> noRepeatDataList2 = noRepeatDataInfoVos2.getMappedResults();
        return noRepeatDataList2;
    }

    @Override
    public List<OrderVo> queryOrderAndUserInfoSort(Sort.Direction direction) {
        Criteria criteria = new Criteria();
        MatchOperation match = Aggregation.match(criteria);
        // 和另外一个集合进行关联，将其作为其属性
        LookupOperation lookup = Aggregation.lookup("UserInfo",
            "userId",// 查询表中字段
            "_id",// 连接表中字段
            "userInfo");// 返回数据所在的属性名称
        SortOperation sort =
            Aggregation.sort(new Sort(direction,"userInfo.type"));
        TypedAggregation<Order> noRepeatAggregation2 =
            Aggregation.newAggregation(Order.class,match,lookup,sort);

        AggregationResults<OrderVo> noRepeatDataInfoVos2 = mongoTemplate.aggregate(noRepeatAggregation2, OrderVo.class);
        List<OrderVo> noRepeatDataList2 = noRepeatDataInfoVos2.getMappedResults();
        return noRepeatDataList2;
    }
}
